介紹
訪問者模式定義一系列對被訪問物件的操作,而不改變被訪問物件的類。
C++範例
#include <iostream>
#include <vector>
class LeafNode;
class InternalNode;
// 抽象訪問者
// 繼承此類來定義如何訪問物件
class Visitor
{
public:
virtual ~Visitor() {}
virtual void Visit(const LeafNode &) = 0;
virtual void Visit(const InternalNode &) = 0;
};
// 具體訪問者
// 定義如何訪問物件
class PrintVisitor : public Visitor
{
public:
void Visit(const LeafNode &)
{
std::cout << "visiting a leafnode" << std::endl;
}
void Visit(const InternalNode &)
{
std::cout << "visiting an internal node" << std::endl;
}
};
// 抽象被訪問物件
// 會被Visitor類訪問
class Node
{
public:
virtual ~Node() {}
// 讓傳入的Visitor訪問自己
virtual void Accept(Visitor &v) = 0;
};
// 具體被訪問物件1 (單節點)
class LeafNode : public Node
{
public:
void Accept(Visitor &v)
{
v.Visit(*this);
}
};
// 具體被訪問物件2 (含有其他節點的節點)
class InternalNode : public Node
{
public:
void Accept(Visitor &v)
{
v.Visit(*this);
for (const auto &elem : m_data)
elem->Accept(v);
}
void Add(Node *pn)
{
m_data.push_back(pn);
}
private:
std::vector<Node *> m_data;
};
int main()
{
LeafNode lna;
LeafNode lnb;
LeafNode lnc;
InternalNode in1;
InternalNode in2;
// 創建節點樹結構
// in1
// ----------------------
// | |
// lna(單節點) in2
// ----------------
// | |
// lnb(單節點) lnc(單節點)
//
//
in1.Add(&lna);
in1.Add(&in2);
in2.Add(&lnb);
in2.Add(&lnc);
PrintVisitor pv;
in1.Accept(pv);
return 0;
}
Output:
visiting an internal node
visiting a leafnode
visiting an internal node
visiting a leafnode
visiting a leafnode
Ref:
https://blog.csdn.net/lanchunhui/article/details/51001558